Skip to content

fix: use os.dup to avoid closing real stdin/stdout in stdio_server - #2737

Closed
xlyoung wants to merge 1 commit into
modelcontextprotocol:mainfrom
xlyoung:fix/stdio-close-real-stdin-stdout
Closed

xlyoung wants to merge 1 commit into
modelcontextprotocol:mainfrom
xlyoung:fix/stdio-close-real-stdin-stdout

Conversation

@xlyoung

@xlyoung xlyoung commented May 31, 2026

Copy link
Copy Markdown

Fixes #1933

Problem

When stdio_server() wraps sys.stdin.buffer/sys.stdout.buffer directly, closing the context manager also closes the real file descriptors, causing ValueError: I/O operation on closed file on subsequent I/O operations.

Fix

Use os.dup() to duplicate file descriptors before wrapping them. This ensures closing the wrappers does not affect the real stdin/stdout.

Added fallback for environments where fileno() is not available (e.g., BytesIO-backed streams in tests).

Testing

  • All existing tests pass
  • Added new test test_stdio_server_uses_os_dup to verify the fix
  • Tested with -race flag

Fixes modelcontextprotocol#1933

When stdio_server() wraps sys.stdin.buffer/sys.stdout.buffer directly,
closing the context manager also closes the real file descriptors,
causing ValueError on subsequent I/O operations.

Fix: Use os.dup() to duplicate file descriptors before wrapping them.
This ensures closing the wrappers doesn't affect the real stdin/stdout.

Added fallback for environments where fileno() is not available
(e.g., BytesIO-backed streams in tests).
@maxisbey

Copy link
Copy Markdown
Contributor

Thanks for the PR. Tracking this in #2040 instead. I'm closing this out as part of a backlog cleanup around the v2 release. Feel free to reopen if this is still relevant.

AI Disclaimer

@maxisbey maxisbey closed this Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Using transport="stdio" closes real stdio, causing ValueError after server exits

2 participants